﻿using AutoMapper;
using Inventorycount.API.Write.Application.Command;
using Inventorycount.Domain;
using Inventorycount.ErrorCode;
using Inventorycount.Infrastructure;
using MediatR;

namespace Inventorycount.API.Write.Application.CommandHandLer
{
    public class DeleteTransferCommandHandLer : IRequestHandler<DeleteTransferCommand, APIResult<int>>
    {
        private readonly IMapper _mapper;
        private readonly ILogger<DeleteTransferCommandHandLer> _logger;
        private readonly SqlSugarHelp<Wms_Transfer_detail> _detailService;
        private readonly SqlSugarHelp<Wms_Transfer_order> _orderService;
        private readonly SqlSugarHelp<Wms_Operation_log> _logService;
        private readonly SqlSugarHelp<Wms_outbound_order> _outboundService;
        private readonly SqlSugarHelp<Wms_outbound_detail> _outboundDetailService;
        private readonly SqlSugarHelp<Wms_inbound_order> _inboundService;
        private readonly SqlSugarHelp<Wms_Inbound_record> _inboundDetailService;

        public DeleteTransferCommandHandLer(
            SqlSugarHelp<Wms_Transfer_detail> detailService,
            SqlSugarHelp<Wms_Transfer_order> orderService,
            IMapper mapper,
            ILogger<DeleteTransferCommandHandLer> logger,
            SqlSugarHelp<Wms_Operation_log> logService,
            SqlSugarHelp<Wms_outbound_order> outboundService,
            SqlSugarHelp<Wms_outbound_detail> outboundDetailService,
            SqlSugarHelp<Wms_inbound_order> inboundService,
            SqlSugarHelp<Wms_Inbound_record> inboundDetailService)
        {
            _detailService = detailService;
            _orderService = orderService;
            _mapper = mapper;
            _logger = logger;
            _logService = logService;
            _outboundService = outboundService;
            _outboundDetailService = outboundDetailService;
            _inboundService = inboundService;
            _inboundDetailService = inboundDetailService;
        }

        public async Task<APIResult<int>> Handle(DeleteTransferCommand request, CancellationToken cancellationToken)
        {
            var result = new APIResult<int>();

            try
            {
                // 1. 先查询要删除的调拨单是否存在
                var transferOrder = await _orderService.SqlSugarClient.Queryable<Wms_Transfer_order>()
                    .Where(x => x.Id == request.Id && !x.IsDeleted)
                    .FirstAsync();

                if (transferOrder == null)
                {
                    result.Code = ResultCode.Fail;
                    result.Message = "调拨单不存在或已被删除";
                    return result;
                }

                // 2. 查询关联的出库单和入库单
                var outboundOrders = await _outboundService.SqlSugarClient.Queryable<Wms_outbound_order>()
                    .Where(x => x.Transfer_id == request.Id && !x.IsDeleted)
                    .ToListAsync();

                var inboundOrders = await _inboundService.SqlSugarClient.Queryable<Wms_inbound_order>()
                    .Where(x => x.Transfer_id == request.Id && !x.IsDeleted)
                    .ToListAsync();

                // 3. 使用事务执行删除操作
                var deleteResult = await _orderService.UseTransactionAsync(async () =>
                {
                    int totalAffectedRows = 0;

                    // 3.1 先删除出库单相关数据
                    if (outboundOrders.Any())
                    {
                        var outboundIds = outboundOrders.Select(x => x.Id).ToList();

                        // 删除出库明细
                        var outboundDetailDeleteResult = await _outboundDetailService.SqlSugarClient.Deleteable<Wms_outbound_detail>()
                            .Where(x => outboundIds.Contains(x.Outbound_id))
                            .ExecuteCommandAsync();
                        totalAffectedRows += outboundDetailDeleteResult;

                        // 删除出库单
                        var outboundDeleteResult = await _outboundService.SqlSugarClient.Deleteable<Wms_outbound_order>()
                            .Where(x => outboundIds.Contains(x.Id))
                            .ExecuteCommandAsync();
                        totalAffectedRows += outboundDeleteResult;
                    }

                    // 3.2 删除入库单相关数据
                    if (inboundOrders.Any())
                    {
                        var inboundIds = inboundOrders.Select(x => x.Id).ToList();

                        // 删除入库明细
                        var inboundDetailDeleteResult = await _inboundDetailService.SqlSugarClient.Deleteable<Wms_Inbound_record>()
                            .Where(x => inboundIds.Contains(x.Inbound_id))
                            .ExecuteCommandAsync();
                        totalAffectedRows += inboundDetailDeleteResult;

                        // 删除入库单
                        var inboundDeleteResult = await _inboundService.SqlSugarClient.Deleteable<Wms_inbound_order>()
                            .Where(x => inboundIds.Contains(x.Id))
                            .ExecuteCommandAsync();
                        totalAffectedRows += inboundDeleteResult;
                    }

                    // 3.3 删除调拨单明细
                    var detailDeleteResult = await _detailService.SqlSugarClient.Deleteable<Wms_Transfer_detail>()
                        .Where(x => x.Transfer_id == request.Id)
                        .ExecuteCommandAsync();
                    totalAffectedRows += detailDeleteResult;

                    // 3.4 软删除调拨单主表
                    var mainDeleteResult = await _orderService.SqlSugarClient.Deleteable<Wms_Transfer_order>()
                        .Where(x => x.Id == request.Id)
                        .ExecuteCommandAsync();
                    totalAffectedRows += mainDeleteResult;

                    // 3.5 记录操作日志
                    var log = new Wms_Operation_log
                    {
                        Transfer_id = request.Id,
                        Operation_type = "删除",
                        operator_id = transferOrder.Operator_id,
                        Operation_desc = $"删除调拨单及相关出库/入库数据，单号:{transferOrder.Transfer_no}",
                        operation_time = DateTime.Now,
                    };
                    await _logService.AddAsync(log);

                    return totalAffectedRows;
                });

                // 4. 处理删除结果
                if (deleteResult > 0)
                {
                    result.Code = ResultCode.Ok;
                    result.Message = "删除调拨单及相关出库/入库数据成功";
                    result.Data = deleteResult;
                }
                else
                {
                    result.Code = ResultCode.Fail;
                    result.Message = "删除调拨单失败";
                }
            }
            catch (Exception ex)
            {
                result.Code = ResultCode.Fail;
                result.Message = "删除调拨单时发生系统错误";
                _logger.LogError($"删除调拨单出现异常，调拨单ID:{request.Id}，错误信息:{ex.Message}", ex);
            }

            return result;
        }
    }
}